package com.chinadaas.hangzhou.archetypeweb.util;

import com.google.common.collect.Maps;
import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.KV;
import io.etcd.jetcd.KeyValue;
import io.etcd.jetcd.kv.GetResponse;
import io.etcd.jetcd.options.DeleteOption;
import io.etcd.jetcd.options.GetOption;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @author Lux Sun
 * @date 2020/6/21
 */
@Component
public class EtcdUtil {

    @Resource
    private KV kv;

    /**
     * 新增 Etcd
     * @param key
     * @param value
     * @return void
     */
    public void putEtcdInfo(String key, String value) throws ExecutionException, InterruptedException {
        kv.put(ByteSequence.from(key, StandardCharsets.UTF_8), ByteSequence.from(value, StandardCharsets.UTF_8)).get();
    }

    /**
     * 删除 Etcd 前缀
     * @param key
     * @return void
     */
    public void delPrefixEtcdInfo(String key) throws ExecutionException, InterruptedException {
        ByteSequence bKey = ByteSequence.from(key, StandardCharsets.UTF_8);
        DeleteOption deleteOption = DeleteOption.newBuilder().withPrefix(bKey).build();
        kv.delete(bKey, deleteOption).get();
    }

    /**
     * 删除 Etcd 精准
     * @param key
     * @return void
     */
    public void delEtcdInfo(String key) throws ExecutionException, InterruptedException {
        ByteSequence bKey = ByteSequence.from(key, StandardCharsets.UTF_8);
        kv.delete(bKey).get();
    }

    static final ByteSequence prefixEndOf(ByteSequence prefix) {
        byte[] endKey = (byte[])prefix.getBytes().clone();

        for(int i = endKey.length - 1; i >= 0; --i) {
            if (endKey[i] < 255) {
                ++endKey[i];
                return ByteSequence.from(Arrays.copyOf(endKey, i + 1));
            }
        }

        return null;
    }

    /**
     * 获取 Etcd
     * @param key
     * @return java.util.Map<java.lang.String,java.lang.String>
     */
    public Map<String, String> getEtcdInfo(String key) throws ExecutionException, InterruptedException {
        GetOption option = GetOption.newBuilder()
                .withPrefix(ByteSequence.from(key, StandardCharsets.UTF_8))
                .build();
        GetResponse getResponse = kv.get(ByteSequence.from(key, StandardCharsets.UTF_8), option).get();
        List<KeyValue> kvs = getResponse.getKvs();
        Map<String, String> kvMap = Maps.newHashMap();
        kvs.forEach(v -> kvMap.put(new String(v.getKey().getBytes()), new String(v.getValue().getBytes())));
        return kvMap;
    }
}